﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Liang.Device;
using Liang.Util.ProtocolDataParser;

namespace Liang.Util
{
    /// <summary>
    /// 静态磅配置类
    /// </summary>
    public class StaticWagonConfigSection : ConfigurationSection
    {
        static StaticWagonConfigSection m_StaticWagonConfig = null;

        public static StaticWagonConfigSection StaticWagonConfig
        {
            get
            {
                if (null == m_StaticWagonConfig)
                {
                    try
                    {
                        m_StaticWagonConfig = (StaticWagonConfigSection)ConfigurationManager.GetSection("StaticWagon");
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                }

                return m_StaticWagonConfig;
            }
        }

        /// <summary>
        /// 串口配置
        /// </summary>
        [ConfigurationProperty("comPort", IsRequired = true)]
        public string ComPortElement
        {
            get { return (string)this["comPort"]; }
            set { this["comPort"] = value; }
        }

        /// <summary>
        /// 数据格式
        /// </summary>
        [ConfigurationProperty("format", IsRequired = true)]
        public string DataFormatElement
        {
            get { return (string)this["format"]; }
            set { this["format"] = value; }
        }

        /// <summary>
        /// 帧头长度
        /// </summary>
        [ConfigurationProperty("headSize", IsRequired = true)]
        public uint HeadSize
        {
            get { return (uint)this["headSize"]; }
            set { this["headSize"] = value; }
        }

        /// <summary>
        /// 帧尾长度
        /// </summary>
        [ConfigurationProperty("endSize", IsRequired = true)]
        public uint EndSize
        {
            get { return (uint)this["endSize"]; }
            set { this["endSize"] = value; }
        }

        /// <summary>
        /// 数据起始位（从0开始）
        /// </summary>
        [ConfigurationProperty("startIndex", IsRequired = true)]
        public int StartIndex
        {
            get { return (int)this["startIndex"]; }
            set { this["startIndex"] = value; }
        }

        /// <summary>
        /// 有效数据长度
        /// </summary>
        [ConfigurationProperty("dataSize", IsRequired = true)]
        public int ValidDataSize
        {
            get { return (int)this["dataSize"]; }
            set { this["dataSize"] = value; }
        }

        /// <summary>
        /// 数据位顺序
        /// </summary>
        [ConfigurationProperty("bigEnd", DefaultValue = "false")]
        public bool BigEnd
        {
            get { return (bool)this["bigEnd"]; }
            set { this["bigEnd"] = value; }
        }

        /// <summary>
        /// 缩放比例（公斤转换为吨的缩放比例）
        /// </summary>
        [ConfigurationProperty("scale", DefaultValue = "1000")]
        public long Scale
        {
            get
            {
                long nTmp = (long)this["scale"];
                if (0 >= nTmp)
                {
                    nTmp = 1;
                }
                return nTmp;
            }
            set { this["scale"] = value; }
        }
    }

    /// <summary>
    /// 通用地磅数据解析时间
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public delegate void ConvertDataHandler(object sender, float fWeight);

    /// <summary>
    /// 通用静态磅
    /// </summary>
    public class StaticWagon : IDisposable
    {
        /// <summary>
        /// 静态磅数据格式配置
        /// </summary>
        StaticWagonConfigSection m_StaticWagonConfig = null;

        /// <summary>
        /// 串口通讯类
        /// </summary>
        ComPort m_ComPort = null;

        /// <summary>
        /// 数据解析类
        /// </summary>
        ParserTool m_DataParser = null;

        public StaticWagon()
        {
            try
            {
                // 加载配置
                m_StaticWagonConfig = StaticWagonConfigSection.StaticWagonConfig;

                // 初始化数据解析类
                byte[] dataFormat = Bytes.HexStringToByteArray(m_StaticWagonConfig.DataFormatElement, new char[] { ',', ' ' });
                m_DataParser = new ParserTool(new ProtocolData(dataFormat, m_StaticWagonConfig.HeadSize, m_StaticWagonConfig.EndSize));
                m_DataParser.ParsedDataEvent += OnParsedData;

                // 初始化串口
                m_ComPort = new ComPort(m_StaticWagonConfig.ComPortElement);
                m_ComPort.ReceivedDataEvent += OnReceivedComPortData;
                m_ComPort.Open();
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        /// <summary>
        /// 解析数据
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        void OnParsedData(byte[] data)
        {
            long nTmp = ParsingData(data);
            // 转换为吨
            float fWeight = (float)nTmp / m_StaticWagonConfig.Scale;
            OnConvertData(fWeight);
        }

        /// <summary>
        /// 收到了串口数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void OnReceivedComPortData(object sender, ReceiveDataArgs e)
        {
            m_DataParser.AddData(e.ReceivedData);
        }

        /// <summary>
        /// 将收到的字节数据解析为读数
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public long ParsingData(byte[] data)
        {
            long ret = 0;
            string strResult = "0";

            try
            {
                if (0 <= m_StaticWagonConfig.StartIndex)
                {
                    if (data.Length >= (m_StaticWagonConfig.StartIndex + m_StaticWagonConfig.ValidDataSize))
                    {
                        System.Text.ASCIIEncoding asciiEncoding = new ASCIIEncoding();

                        List<byte> tmpData = new List<byte>(data);

                        byte[] inBuffer = new byte[m_StaticWagonConfig.ValidDataSize];
                        tmpData.CopyTo(m_StaticWagonConfig.StartIndex, inBuffer, 0, m_StaticWagonConfig.ValidDataSize);

                        if (m_StaticWagonConfig.BigEnd)
                        {
                            strResult = asciiEncoding.GetString(inBuffer, 0, inBuffer.Length);
                        }
                        else
                        {
                            byte[] tmpReversed = inBuffer.Reverse().ToArray();
                            strResult = asciiEncoding.GetString(tmpReversed, 0, tmpReversed.Length);
                        }

                        ret = long.Parse(strResult);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return ret;
        }

        // 声明事件
        public event ConvertDataHandler ConvertDataEvent;

        // 事件处理函数
        protected virtual void OnConvertData(float fWeight)
        {
            if (null != ConvertDataEvent)
            {
                ConvertDataEvent(this, fWeight);
            }
        }

        public void Dispose()
        {
            if (null != m_ComPort)
            {
                m_ComPort.Close();
            }
        }
    }
}
